package com.ruoyi.tjfx.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.base.domain.SyType;
import com.ruoyi.base.mapper.SyTypeMapper;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.BigDecimalUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.syrw.domain.BsDataReport;
import com.ruoyi.syrw.mapper.BsDataReportMapper;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.tjfx.domain.ReportMonthlyBo;
import com.ruoyi.tjfx.domain.ReportMonthlyVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class ReportMonthlyService {

    //试验类型
    private final SyTypeMapper syTypeMapper;
    //试验任务
    private final BsDataReportMapper bsDataReportMapper;
    private final SysDeptMapper deptMapper;
    private final SysDictDataMapper dictDataMapper;

    /**承包人对应施工试验室数据；
     * 监理人对应驻地试验室数据；
     * 中心试验室对应总监办试验室数据；
     *
     * -- 试验任务数据
     * SELECT * FROM  syrw_bs_data_report;
     * SELECT * FROM  ww_bs_wwsy;
     * -- 试验分类
     *  SELECT * FROM  base_sy_type;
     * -- 组织
     * select * from sys_dept;
     * -- 用户
     * select d.dept_name,s.* from sys_user s,sys_dept d where s.dept_id = d.dept_id;
     *
     * */
    public TableDataInfo monthlyReport(ReportMonthlyBo bo) {
        //判断当前用户是
        Long deptId = bo.getDeptId();
        SysDept sysDept = deptMapper.selectVoById(deptId);
        String ancestors = sysDept.getAncestors();
        String[] split = ancestors.split(",");
        //总监办，只查本试验室下的数据；
        if(split.length == 4){
            return TableDataInfo.build(getOwnData(bo,deptId,1));
        //驻地试验室,查询驻地试验室和其下的施工试验室；
        } else if (split.length == 5){
            //本驻地试验室下的数据；
            List<ReportMonthlyVo> ownData = getOwnData(bo, deptId,2);
            //其下的施工试验室数据；
            LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysDept::getParentId,deptId);
            List<SysDept> sysDepts = deptMapper.selectList(wrapper);
            if(CollUtil.isNotEmpty(sysDepts)) {
                SysDept dept = sysDepts.get(0);
                List<ReportMonthlyVo> subData = getOwnData(bo, dept.getDeptId(), 3);
                if(CollUtil.isNotEmpty(ownData)&&CollUtil.isNotEmpty(subData)) {
                    for (int i = 0; i < ownData.size(); i++) {
                        ownData.get(i).setChengbrhgl(subData.get(i).getChengbrhgl());
                        ownData.get(i).setChengbrzs(subData.get(i).getChengbrzs());
                        Integer chengbrkglj = subData.get(i).getChengbrkglj() == null ? 0 : subData.get(i).getChengbrkglj();
                        Integer jianlrkglj = ownData.get(i).getJianlrkglj() == null ? 0 : ownData.get(i).getJianlrkglj();
                        //抽检频率
                        BigDecimal choujpl = BigDecimalUtil.divide(BigDecimalUtil.multiply(BigDecimal.valueOf(100), BigDecimal.valueOf(jianlrkglj)), BigDecimal.valueOf(chengbrkglj));
                        ownData.get(i).setChoujpl(choujpl);
                        //开工累计
                        ownData.get(i).setChengbrkglj(chengbrkglj);
                    }
                } else if(CollUtil.isNotEmpty(ownData)&&CollUtil.isEmpty(subData)){
                    for (int i = 0; i < ownData.size(); i++) {
                        ownData.get(i).setChengbrhgl(BigDecimal.ZERO);
                        ownData.get(i).setChengbrzs(0);
                        ownData.get(i).setChoujpl(BigDecimal.ZERO);
                        ownData.get(i).setChengbrkglj(0);
                    }
                } else if(CollUtil.isNotEmpty(subData)&&CollUtil.isEmpty(ownData)){
                    for(int i = 0 ;i<subData.size();i++){
                        subData.get(i).setJianlrkglj(0);
                        subData.get(i).setJianlrhgl(BigDecimal.ZERO);
                        subData.get(i).setJianlrzs(0);
                        subData.get(i).setChoujpl(BigDecimal.ZERO);
                        ownData = subData;
                    }
                }
            }
            return TableDataInfo.build(ownData);
            //施工试验室，只查本试验室数据，
        } else if (split.length == 6) {
            return TableDataInfo.build(getOwnData(bo,deptId,3));
        }
        return TableDataInfo.build();
    }

    //获取本试验室下的数据；
    private List<ReportMonthlyVo> getOwnData(ReportMonthlyBo bo, Long deptId, int i) {
        //查询试验任务和外委数据；
        List<BsDataReport> bsDataReports = bsDataReportMapper.selectListAll(deptId);
        if (CollUtil.isEmpty(bsDataReports)) {
            return new ArrayList<>();
        }
        Map<String, Object> params = bo.getParams();
        Object beginReportDate = params.get("beginReportDate");
        Object endReportDate = params.get("endReportDate");
        Date begin = null;
        Date end = null;
        if (beginReportDate != null && endReportDate != null) {
            begin = DateUtils.dateTime("yyyy-MM-dd", beginReportDate.toString());
            end = DateUtils.dateTime("yyyy-MM-dd", endReportDate.toString());
        }
        //当月数据（包括搜索条件内的日期和当月的日期数据）
        List<BsDataReport> currentMonthDatas;
        //如果试验日期过滤条件不为空；
        if (begin != null && end != null) {
            Date finalBegin = begin;
            Date finalEnd = end;
            currentMonthDatas = bsDataReports.stream().filter(e -> e.getReportDateEnd() != null ? between(finalBegin, finalEnd, e.getReportDateEnd()) :
                between(finalBegin, finalEnd, e.getReportDate())).collect(Collectors.toList());
            //如果为空，就查本月的试验数据；
        } else {
            LocalDate currentDate = LocalDate.now();
            currentMonthDatas = bsDataReports.stream().filter(e -> isCurrentMonth(e, currentDate)).collect(Collectors.toList());
        }
        Map<Long, List<BsDataReport>> currentMonths = currentMonthDatas.stream().collect(Collectors.groupingBy(BsDataReport::getSyType));
        Map<Long, List<BsDataReport>> totalMaps = bsDataReports.stream().collect(Collectors.groupingBy(BsDataReport::getSyType));
        //试验大类字典数据；
        List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType("sy_big_type");
        Map<String, String> bigTypeMap = dictDatas.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //试验分类
        List<SyType> syTypes = syTypeMapper.selectList().stream().filter(e -> StringUtils.equals("0", e.getDelFlag())).collect(Collectors.toList());
        //syTypeId和syTypeName映射；
        Map<Long, SyType> syTypeMap = syTypes.stream().collect(Collectors.toMap(SyType::getSyTypeId, e -> e));
        //试验分类二级类型；
        List<SyType> syTypeList = syTypes.stream().filter(e -> e.getLevel() == 2).sorted((x, y) -> x.getSort() - y.getSort()).collect(Collectors.toList());
        //组装返回值数据；
        List<ReportMonthlyVo> result = new ArrayList<>();
        if (CollUtil.isNotEmpty(syTypeList)) {
            //遍历二级试验分类；
            syTypeList.forEach(e -> {
                Long key = e.getSyTypeId();
                ReportMonthlyVo vo = new ReportMonthlyVo();
                //试验大类
                Assert.notNull(e.getSyBigType(), "空指针 e.getSyBigType() :" + e.toString());
                vo.setXuh(bigTypeMap.get(e.getSyBigType().toString()));
                //试验类型一级分类
                Assert.notNull(syTypeMap.get(e.getParentId()), "空指针 syTypeMap.get(e.getParentId()); e.getParentId() = " + e.getParentId() + "syTypeMap = " + syTypeMap.toString());
                vo.setName(syTypeMap.get(e.getParentId()).getSyTypeName());
                //试验类型二级分类
                vo.setTitle(e.getSyTypeName());
                //承包人数据（施工试验室；）
                if(i == 3){
                    if (CollUtil.isEmpty(currentMonths)) {
                        vo.setChengbrhgl(BigDecimal.ZERO);
                        vo.setChengbrzs(0);
                    } else {
                        //计算合格率
                        List<BsDataReport> bsDatas = currentMonths.get(key);
                        if (CollUtil.isEmpty(bsDatas)) {
                            vo.setChengbrhgl(BigDecimal.ZERO);
                        } else {
                            int heg = (int) bsDatas.stream().filter(item -> item.getReportResult() == 1).count();
                            int hg = heg * 100;
                            BigDecimal hegl = BigDecimalUtil.divide(BigDecimal.valueOf(hg), BigDecimal.valueOf(bsDatas.size()), 2);
                            //合格率
                            vo.setChengbrhgl(hegl);
                        }
                        //本月组数；
                        vo.setChengbrzs(currentMonths.get(key) == null ? 0 : currentMonths.get(key).size());
                    }
                    //开工累计
                    vo.setChengbrkglj(totalMaps.get(key) == null ? 0 : totalMaps.get(key).size());
                } else if(i == 1) {
                    //中心试验室数据；
                    //承包人
                    vo.setChengbrhgl(BigDecimal.ZERO);
                    vo.setChengbrzs(0);
                    vo.setChengbrkglj(0);
                    //监理人
                    vo.setJianlrhgl(BigDecimal.ZERO);
                    vo.setJianlrzs(0);
                    vo.setJianlrkglj(0);
                    vo.setChoujpl(BigDecimal.ZERO);
                    //中心试验室；
                    if (CollUtil.isEmpty(currentMonths)) {
                        vo.setZhongxsyshgl(BigDecimal.ZERO);
                        vo.setZhongxsyszs(0);
                    } else {
                        //计算合格率
                        List<BsDataReport> bsDatas = currentMonths.get(key);
                        if (CollUtil.isEmpty(bsDatas)) {
                            vo.setZhongxsyshgl(BigDecimal.ZERO);
                        } else {
                            int heg = (int) bsDatas.stream().filter(item -> item.getReportResult() == 1).count();
                            int hg = heg * 100;
                            BigDecimal hegl = BigDecimalUtil.divide(BigDecimal.valueOf(hg), BigDecimal.valueOf(bsDatas.size()), 2);
                            //合格率
                            vo.setZhongxsyshgl(hegl);
                        }
                        //本月组数；
                        vo.setZhongxsyszs(currentMonths.get(key) == null ? 0 : currentMonths.get(key).size());
                    }
                    //开工累计
                    vo.setZhongxsyskglj(totalMaps.get(key) == null ? 0 : totalMaps.get(key).size());
                } else if(i == 2) {
                    if (CollUtil.isEmpty(currentMonths)) {
                        vo.setJianlrhgl(BigDecimal.ZERO);
                        vo.setJianlrzs(0);
                    } else {
                        //计算合格率
                        List<BsDataReport> bsDatas = currentMonths.get(key);
                        if (CollUtil.isEmpty(bsDatas)) {
                            vo.setJianlrhgl(BigDecimal.ZERO);
                        } else {
                            int heg = (int) bsDatas.stream().filter(item -> item.getReportResult() == 1).count();
                            int hg = heg * 100;
                            BigDecimal hegl = BigDecimalUtil.divide(BigDecimal.valueOf(hg), BigDecimal.valueOf(bsDatas.size()), 2);
                            //合格率
                            vo.setJianlrhgl(hegl);
                        }
                        //本月组数；
                        vo.setJianlrzs(currentMonths.get(key) == null ? 0 : currentMonths.get(key).size());
                    }
                    //开工累计
                    vo.setJianlrkglj(totalMaps.get(key) == null ? 0 : totalMaps.get(key).size());
                }
                result.add(vo);
            });
            return result;
        }
        return new ArrayList<>();
    }

    //判断试验日期是否是当月；
    private boolean isCurrentMonth(BsDataReport e,LocalDate currentDate) {
        Calendar calendar = Calendar.getInstance();
        if (e.getReportDateEnd() != null) {
            calendar.setTime(e.getReportDateEnd());
            LocalDate localDate = LocalDate.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH));
            return currentDate.getYear() == localDate.getYear() && currentDate.getMonthValue() == localDate.getMonthValue();
        } else if (e.getReportDate() != null) {
            calendar.setTime(e.getReportDate());
            LocalDate localDate = LocalDate.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH));
            return currentDate.getYear() == localDate.getYear() && currentDate.getMonthValue() == localDate.getMonthValue();
        }
        return false;
    }

    //比较指定日期是否在两个日期之间；
    private boolean between(Date begin, Date end, Date param) {
        if(begin == null || end == null || param == null){
            return false;
        }
        return begin.compareTo(param) <= 0 && end.compareTo(param) >= 0;
    }


}
